package com.lingx.web.core;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.HttpServerExpectContinueHandler;
import io.netty.handler.stream.ChunkedWriteHandler;

public class FileUploadServer implements Runnable {
	private int port=9877;
	public FileUploadServer(int port) {
		this.port=port;
	}
	public void startServer() {
		try {
			EventLoopGroup boss = new NioEventLoopGroup(1);
			EventLoopGroup worker = new NioEventLoopGroup(2);
			ServerBootstrap serverBootstrap = new ServerBootstrap();

			try {
			    serverBootstrap
			        .group(boss, worker)
			        .channel(NioServerSocketChannel.class)
			        .childHandler(new ChannelInitializer<SocketChannel>() {
			            @Override
			            protected void initChannel(SocketChannel ch) throws Exception {
			                ch.pipeline().addLast( new HttpServerCodec(4096, 8192, 1024 * 1024 * 10));
			                ch.pipeline().addLast(new HttpObjectAggregator(1024 * 1024*10));// 参数是上传最大附件的大小，单位是Bit
			                ch.pipeline().addLast(new HttpServerExpectContinueHandler());
			                // 新增ChunkedHandler，主要作用是支持异步发送大的码流（例如大文件传输），但是不占用过多的内存，防止发生java内存溢出错误
			                ch.pipeline().addLast(new ChunkedWriteHandler());
			                // 用于下载文件
			                ch.pipeline().addLast(new HttpDownloadHandler());
			                ch.pipeline().addLast(new FileUploadRequestHandler());
			            }
			        });

			    ChannelFuture future = serverBootstrap.bind(this.port).sync();
			    future.channel().closeFuture().sync();
			} finally {
			    boss.shutdownGracefully();
			    worker.shutdownGracefully();
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	@Override
	public void run() {
		startServer();
	}
}
